package org.ramoths.netcom.sessions;

import java.net.Socket;

import org.ramoths.netcom.outils.Outils;
import org.ramoths.netcom.sessions.exceptions.CommunicationException;

public class SessionMessage
{
	private final Socket socket;
	private final byte[] cleLocale;
	private long sequenceIVLocale;
	private final byte[] cleDistante;
	private long sequenceIVDistante;
	
	public SessionMessage(Socket socket, SessionParametres parametres)
	{
		this.socket = socket;
		this.cleLocale = parametres.getCleLocale();
		this.sequenceIVLocale = parametres.getSequenceIVLocale();
		this.cleDistante = parametres.getCleDistante();
		this.sequenceIVDistante = parametres.getSequenceIVDistante();
	}
	
	private final Object moniteurEnvoi = new Object();
	public void envoyer(byte[] donnees) throws CommunicationException
	{
		synchronized (moniteurEnvoi)
		{
			try
			{
				byte[] donneesCryptes = Outils.crypterAES(donnees, cleLocale, sequenceIVLocale++);
				socket.getOutputStream().write(Outils.desInt(donneesCryptes.length));
				socket.getOutputStream().write(donneesCryptes);
			}
			catch (Exception ex)
			{
				throw new CommunicationException("Erreur d'envoi de message!", ex);
			}
		}
	}
	
	private final Object moniteurReception = new Object();
	public byte[] recevoir() throws CommunicationException
	{
		byte[] donnees = null;
		synchronized (moniteurReception)
		{
			try
			{
				int taille = Outils.assInt(Outils.lectureFlux(socket.getInputStream(), 4), 0);
				donnees = Outils.decrypterAES(Outils.lectureFlux(socket.getInputStream(), taille), cleDistante, sequenceIVDistante++);
			}
			catch (Exception ex)
			{
				throw new CommunicationException("Erreur de reception d'objet!", ex);
			}
		}
		return donnees;
	}
	
	public void fermer()
	{
		try
		{
			socket.close();
		}
		catch (Exception ex)
		{
			/* Ne rien faire */
		}
	}
}
